﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using McTools.Xrm.Connection;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Tanguy.WinForm.Utilities.DelegatesHelpers;

namespace SiteMapEditor.Forms.WebRessources
{
    public partial class WebResourcePicker : Form
    {
        #region Variables

        /// <summary>
        /// Web resource type enumeration
        /// </summary>
        public enum WebResourceType
        {
            WebPage = 1,
            Css = 2,
            Script = 3,
            Data = 4,
            Image=  5,
            Silverlight = 8,
            Xsl = 9,
            Ico = 10
        }

        /// <summary>
        /// Manager to connect to a CRM server
        /// </summary>
        private ConnectionManager cManager;

        /// <summary>
        /// Requested web resource type
        /// </summary>
        private int requestedType;

        #endregion Variables

        #region Properties

        /// <summary>
        /// Gets or sets the selected web resource
        /// </summary>
        public string SelectedResource { get; set; }

        #endregion Properties

        #region Constructor

        /// <summary>
        /// Initializes a new instance of class WebResourcePicker
        /// </summary>
        /// <param name="type">Type of web resource to select</param>
        public WebResourcePicker(WebResourceType type)
        {
            InitializeComponent();

            this.requestedType = (int)type;

            // Disables controls
            ListViewDelegates.SetEnableState(this.lstWebResources, false);
            CommonDelegates.SetEnableState(this.btnWebResourcePickerCancel, false);
            CommonDelegates.SetEnableState(this.btnWebResourcePickerValidate, false);
            CommonDelegates.SetEnableState(this.btnNewResource, false);

            if (MainForm.service == null)
            {
                // Connect
                this.cManager = new ConnectionManager(this);
                this.cManager.ConnectionSucceed += new ConnectionManager.ConnectionSucceedEventHandler(cManager_ConnectionSucceed);
                this.cManager.ConnectionFailed += new ConnectionManager.ConnectionFailedEventHandler(cManager_ConnectionFailed);
                this.cManager.AskForConnection(null);
            }
            else
            {
                // Run work
                BackgroundWorker worker = new BackgroundWorker();
                worker.DoWork += new DoWorkEventHandler(worker_DoWork);
                worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
                worker.RunWorkerAsync();
            }
        }

        
        #endregion Constructor

        #region Connection Manager events

        void cManager_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            CommonDelegates.DisplayMessageBox(this, "Connection error: " + e.FailureReason, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            ListViewDelegates.SetEnableState(this.lstWebResources, false);
        }

        void cManager_ConnectionSucceed(object sender, ConnectionSucceedEventArgs e)
        {
            MainForm.service = e.OrganizationService;
            if (this.requestedType == 1)
                this.FillHtmlList();
            else
                this.FillImageList();
        }

        #endregion Connection Manager events

        #region Methods

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (this.requestedType == 1)
                this.FillHtmlList();
            else
                this.FillImageList();
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(this, CrmExceptionHelper.GetErrorMessage(e.Error, false), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
        }

        private void BtnRefreshClick(object sender, EventArgs e)
        {
            lstWebResources.Items.Clear();

            if (this.requestedType == 1)
                this.FillHtmlList();
            else
                this.FillImageList();
        }

        private void FillImageList()
        {
            ListViewDelegates.ClearItems(this.lstWebResources);

            if (MainForm.webResourcesImageCache == null || MainForm.webResourcesImageCache.Count == 0)
            {
                MainForm.webResourcesImageCache = new List<Entity>();

                QueryExpression qe = new QueryExpression("webresource");

                ConditionExpression ce = new ConditionExpression();
                ce.AttributeName = "webresourcetype";

                if (this.requestedType == (int)WebResourceType.Image)
                {
                    ce.Operator = ConditionOperator.In;
                    ce.Values.AddRange(5, 6, 7);
                }
                else
                {
                    ce.Operator = ConditionOperator.Equal;
                    ce.Values.Add(requestedType);
                }

                qe.Criteria.AddCondition(ce);
                qe.ColumnSet.AllColumns = true;

                EntityCollection ec = MainForm.service.RetrieveMultiple(qe);

                foreach (Entity webresource in ec.Entities)
                {
                    MainForm.webResourcesImageCache.Add(webresource);
                }
            }

            foreach (Entity webresource in MainForm.webResourcesImageCache)
            {
                ListViewItem item = new ListViewItem(webresource.Contains("displayname") ? webresource["displayname"].ToString() : "N/A");
                item.SubItems.Add(webresource["name"].ToString());
                item.Tag = webresource;

                ListViewDelegates.AddItem(this.lstWebResources, item);
            }

            ListViewDelegates.Sort(this.lstWebResources);
            ListViewDelegates.SetEnableState(this.lstWebResources, true);
            CommonDelegates.SetEnableState(this.btnWebResourcePickerCancel, true);
            CommonDelegates.SetEnableState(this.btnWebResourcePickerValidate, true);
            CommonDelegates.SetEnableState(this.btnNewResource, true);
            CommonDelegates.SetEnableState(this.btnRefresh, true);
        }

        private void FillHtmlList()
        {
            ListViewDelegates.ClearItems(this.lstWebResources);

            if (MainForm.webResourcesHtmlCache == null || MainForm.webResourcesHtmlCache.Count == 0)
            {
                MainForm.webResourcesHtmlCache = new List<Entity>();

                QueryExpression qe = new QueryExpression("webresource");

                ConditionExpression ce = new ConditionExpression();
                ce.AttributeName = "webresourcetype";

                if (this.requestedType == (int)WebResourceType.Image)
                {
                    ce.Operator = ConditionOperator.In;
                    ce.Values.AddRange(5, 6, 7);
                }
                else
                {
                    ce.Operator = ConditionOperator.Equal;
                    ce.Values.Add(requestedType);
                }

                qe.Criteria.AddCondition(ce);
                qe.ColumnSet.AllColumns = true;

                EntityCollection ec = MainForm.service.RetrieveMultiple(qe);

                foreach (Entity webresource in ec.Entities)
                {
                    MainForm.webResourcesHtmlCache.Add(webresource);
                }
            }

            foreach (Entity webresource in MainForm.webResourcesHtmlCache)
            {
                ListViewItem item = new ListViewItem(webresource.Contains("displayname") ? webresource["displayname"].ToString() : "N/A");
                item.SubItems.Add(webresource["name"].ToString());
                item.Tag = webresource;

                ListViewDelegates.AddItem(this.lstWebResources, item);
            }

            ListViewDelegates.Sort(this.lstWebResources);
            ListViewDelegates.SetEnableState(this.lstWebResources, true);
            CommonDelegates.SetEnableState(this.btnWebResourcePickerCancel, true);
            CommonDelegates.SetEnableState(this.btnWebResourcePickerValidate, true);
            CommonDelegates.SetEnableState(this.btnNewResource, true);
            CommonDelegates.SetEnableState(this.btnRefresh, true);
        }

        private void btnNewResource_Click(object sender, EventArgs e)
        {
            CreateWebResourceDialog cwrDialog = new CreateWebResourceDialog((CreateWebResourceDialog.WebResourceType)requestedType);
            cwrDialog.StartPosition = FormStartPosition.CenterParent;

            if (cwrDialog.ShowDialog() == DialogResult.OK)
            {
                ListViewItem item = new ListViewItem(cwrDialog.CreatedEntity["displayname"].ToString());
                item.SubItems.Add(cwrDialog.CreatedEntity["name"].ToString());
                item.Tag = cwrDialog.CreatedEntity;

                this.lstWebResources.Items.Add(item);
                this.lstWebResources.Sort();
            }
        }

        private void lstWebResources_DoubleClick(object sender, EventArgs e)
        {
            if (this.lstWebResources.SelectedItems.Count > 0)
            {
                Entity webresource = (Entity)this.lstWebResources.SelectedItems[0].Tag;
                this.SelectedResource = webresource["name"].ToString(); ;
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void btnWebResourcePickerValidate_Click(object sender, EventArgs e)
        {
            if (this.lstWebResources.SelectedItems.Count > 0)
            {
                this.SelectedResource = this.lstWebResources.SelectedItems[0].SubItems[1].Text;
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            else
            {
                MessageBox.Show(this, "Please select a web resource!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void btnWebResourcePickerCancel_Click(object sender, EventArgs e)
        {
            this.SelectedResource = null;
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        #endregion Methods
    }
}
